<template>
  <div class="form-editor-container">
    <div class="toolbar">
      <el-button-group>
        <el-button type="primary" @click="saveForm">保存</el-button>
        <el-button @click="resetForm">重置</el-button>
        <el-button @click="previewForm">预览</el-button>
      </el-button-group>
    </div>
    <div class="editor-container">
      <div class="schema-editor">
        <h3>表单结构</h3>
        <el-input
          type="textarea"
          v-model="schemaString"
          :rows="20"
          :autosize="{ minRows: 20 }"
          @input="updateSchema"
          placeholder="请输入JSON Schema"
        ></el-input>
      </div>
      <div class="form-preview" v-if="showPreview">
        <h3>表单预览</h3>
        <div class="form-container">
          <json-forms
            v-if="isValidSchema"
            :schema="schema"
            :uischema="uiSchema"
            :data="formData"
            @change="onChange"
          />
          <div v-else class="error-message">
            <el-alert
              title="JSON Schema 格式错误"
              type="error"
              :description="schemaError"
              show-icon
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, computed, onMounted, watch } from 'vue';
import { JsonForms } from '@jsonforms/vue';
import { vanillaRenderers } from '@jsonforms/vue-vanilla';

export default {
  name: 'FormEditor',
  components: {
    JsonForms
  },
  props: {
    initialSchema: {
      type: Object,
      default: () => ({})
    },
    initialUiSchema: {
      type: Object,
      default: () => ({})
    }
  },
  emits: ['save', 'error'],
  setup(props, { emit }) {
    const schema = ref(props.initialSchema || getDefaultSchema());
    const uiSchema = ref(props.initialUiSchema || getDefaultUiSchema());
    const formData = ref({});
    const schemaString = ref(JSON.stringify(schema.value, null, 2));
    const isValidSchema = ref(true);
    const schemaError = ref('');
    const showPreview = ref(true);

    function getDefaultSchema() {
      return {
        type: 'object',
        properties: {
          name: {
            type: 'string',
            title: '姓名'
          },
          email: {
            type: 'string',
            format: 'email',
            title: '邮箱'
          },
          reason: {
            type: 'string',
            title: '原因',
            maxLength: 500
          }
        },
        required: ['name', 'email', 'reason']
      };
    }

    function getDefaultUiSchema() {
      return {
        type: 'VerticalLayout',
        elements: [
          {
            type: 'Control',
            scope: '#/properties/name'
          },
          {
            type: 'Control',
            scope: '#/properties/email'
          },
          {
            type: 'Control',
            scope: '#/properties/reason',
            options: {
              multi: true
            }
          }
        ]
      };
    }

    const updateSchema = () => {
      try {
        const parsedSchema = JSON.parse(schemaString.value);
        schema.value = parsedSchema;
        isValidSchema.value = true;
        schemaError.value = '';
      } catch (error) {
        isValidSchema.value = false;
        schemaError.value = error.message;
      }
    };

    const saveForm = () => {
      if (!isValidSchema.value) {
        emit('error', '表单结构格式错误，无法保存');
        return;
      }

      try {
        const formDefinition = {
          schema: schema.value,
          uiSchema: uiSchema.value
        };
        emit('save', formDefinition);
      } catch (error) {
        emit('error', '保存表单失败: ' + error.message);
      }
    };

    const resetForm = () => {
      schema.value = getDefaultSchema();
      uiSchema.value = getDefaultUiSchema();
      formData.value = {};
      schemaString.value = JSON.stringify(schema.value, null, 2);
      isValidSchema.value = true;
      schemaError.value = '';
    };

    const previewForm = () => {
      showPreview.value = !showPreview.value;
    };

    const onChange = (event) => {
      formData.value = event.data;
    };

    onMounted(() => {
      if (props.initialSchema) {
        schema.value = props.initialSchema;
        schemaString.value = JSON.stringify(props.initialSchema, null, 2);
      }
      if (props.initialUiSchema) {
        uiSchema.value = props.initialUiSchema;
      }
    });

    return {
      schema,
      uiSchema,
      formData,
      schemaString,
      isValidSchema,
      schemaError,
      showPreview,
      saveForm,
      resetForm,
      previewForm,
      updateSchema,
      onChange,
      renderers: vanillaRenderers
    };
  }
};
</script>

<style scoped>
.form-editor-container {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.toolbar {
  padding: 10px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #dcdfe6;
}

.editor-container {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.schema-editor {
  flex: 1;
  padding: 10px;
  border-right: 1px solid #dcdfe6;
  overflow: auto;
}

.form-preview {
  flex: 1;
  padding: 10px;
  overflow: auto;
}

.form-container {
  padding: 15px;
  background-color: #ffffff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.error-message {
  margin-top: 10px;
}

h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #606266;
  font-size: 16px;
}
</style> 